﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Twodi.Arguments;

namespace Twodi.Input.Events
{
    /// <summary>
    /// Delegate do handler de input.
    /// </summary>
    /// <typeparam name="TEventArgs">Tipo dos argumentos.</typeparam>
    /// <param name="sender">Objeto que levantou o evento.</param>
    /// <param name="e">Argumentos do evento.</param>
    /// <returns>Lista de eventos deve continuar?</returns>
    public delegate bool InputEventHandler<TEventArgs>(object sender, TEventArgs e);

    /// <summary>
    /// Evento de input abstrato.
    /// </summary>
    /// <typeparam name="T">Tipo do Type do Evento.</typeparam>
    /// <typeparam name="M">Tipo do Input.</typeparam>
    public abstract class AbstractInputEvent<T, M>
    {
        /// <summary>
        /// Tipo do Evento.
        /// </summary>
        public T Type
        {
            get;
            set;
        }

        /// <summary>
        /// Construtor default.
        /// </summary>
        /// <param name="type"></param>
        public AbstractInputEvent(T type)
        {
            Type = type;
        }

        /// <summary>
        /// Construtor default.
        /// </summary>
        /// <param name="type"></param>
        public AbstractInputEvent(T type, InputEventHandler<InputEventArgs<M>> method)
        {
            Type = type;
            this.Events += method;
        }

        /// <summary>
        /// Gerenciar o input.
        /// </summary>
        /// <param name="input">Input.</param>
        /// <returns>True se deve continuar a dar handle. False se deve ser parado o handle.</returns>
        public abstract bool Handle(M input);

        /// <summary>
        /// Eventos invocados caso input seja ativado.
        /// </summary>
        public event InputEventHandler<InputEventArgs<M>> Events;

        /// <summary>
        /// Método responsavel por invocar os eventos.
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        protected virtual bool onEvents(InputEventArgs<M> e)
        {
            if (Events != null)
            {
                return Events(this, e);
            }
            return false;
        }
    }
}
